package com.huang.wishstar.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huang.wishstar.entity.Memory;
import com.huang.wishstar.entity.vo.CountDownMemory;
import com.huang.wishstar.entity.vo.CountMemory;
import com.huang.wishstar.entity.vo.GetAllMemoryVO;
import com.huang.wishstar.entity.vo.GetMemoryVO;
import com.huang.wishstar.service.MemoryService;
import com.huang.wishstar.service.UsersService;
import com.huang.wishstar.utils.ApiResponse;
import com.huang.wishstar.utils.Converter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author hmx
 * @since 2021-09-17
 */
@Api(tags = "纪念日管理" ,description = "MemoryController")
@RestController
@RequestMapping("/memory")
public class MemoryController {
    @Autowired
    UsersService usersService;
    @Autowired
    MemoryService memoryService;

    @ApiOperation(value = "纪念日页/根据memoryId删除一个纪念日", notes = "")
    @DeleteMapping("/delete/{memoryId}")
    public ApiResponse<String> DeleteWishById(@ApiParam(value="纪念日id",required = true) @PathVariable("memoryId") Integer memoryId){
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("memory_id",memoryId);
        Boolean b = memoryService.remove(wrapper);
        if (b == true){
            return ApiResponse.<String>builder().code(200).message("删除成功").data(b.toString()).build();
        }
        else {
            return ApiResponse.<String>builder().code(400).message("删除失败").data(b.toString()).build();
        }
    }

    @ApiOperation(value = "纪念日页/创建一个新的纪念日", notes = "type为1表示正计时，type为2表示倒计时。isRepeat只有倒计时即type为2时需要设置，表示该倒计时纪念日是否要年重复，0不重复1重复。纪念日日期memoryDate类型为LocalDate,前端可用这行代码完成:LocalDate memoryDate = LocalDate.of(2021,9,26)，年月日是前端通过选择器选择。前端传入时需判断正计时日期必须小于等于今日日期，倒计时日期必须大于今日日期")
    @PostMapping("/create")
    public ApiResponse<String> create(@ApiParam(value="纪念日信息,memoryId不用传，其他字段都要传。memoryDate为LocalDate型。",required = true) @RequestBody(required=true) Memory requestData){

        Boolean flag = memoryService.save(requestData);
        if(flag==true){
            return ApiResponse.<String>builder().code(200).message("新建成功").data(null).build();}
        else{
            return ApiResponse.<String>builder().code(400).message("新建失败").data(null).build();
        }
    }

    @ApiOperation(value = "纪念日页/查找某用户的所有纪念日(旧)", notes = "dayNum：间隔天数。type=1时为正计时天数，type=2时为倒计时天数。")
    @GetMapping("/getAll/{userId}")
    @ResponseBody
    public ApiResponse<List<GetAllMemoryVO>> getMyAllMemory(@ApiParam(value="用户id",required = true) @PathVariable(value="userId",required=true) Integer userId) {
        //查询条件：user_id一致，且时间合适
        QueryWrapper<Memory> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId).orderByDesc("type");
        List<Memory> memoryEntities = memoryService.list(wrapper);
        //将查出来的实体列表转为Vo列表。
        List<GetAllMemoryVO> getAllMemoryVOList = new ArrayList<>();
        //遍历实体类列表，判断日期
        for(int i=0;i<memoryEntities.size();i++){
            LocalDate memoryDate = memoryEntities.get(i).getMemoryDate();
            LocalDate todayDate = LocalDate.now();
            GetAllMemoryVO getAllMemoryVo = new GetAllMemoryVO();
            if(memoryEntities.get(i).getType() == 1 && todayDate.isAfter(memoryDate)){
                long dayNum= memoryDate.until(todayDate, ChronoUnit.DAYS);
                System.out.println("正计时，daynum="+dayNum+",memoryId="+memoryEntities.get(i).getMemoryId());
                getAllMemoryVo.setDayNum(Converter.getAsInteger(dayNum));
                getAllMemoryVo.setMemoryId(memoryEntities.get(i).getMemoryId());
                getAllMemoryVo.setMemoryDate( memoryEntities.get(i).getMemoryDate());
                getAllMemoryVo.setMemoryTitle( memoryEntities.get(i).getMemoryTitle());
                getAllMemoryVo.setType( memoryEntities.get(i).getType());
                getAllMemoryVo.setIsRepeat( memoryEntities.get(i).getIsRepeat());
                getAllMemoryVOList.add(getAllMemoryVo);
                continue;
            }
            //如果是倒计时,四种情况：不重复且超期了就不返回给前端该记录；不重复未超期或重复未超期都返回记录；重复但超期修改年份且返回记录
            if(memoryEntities.get(i).getType() == 2 ){
                //如果用户设置了该纪念日不重复，而且今天已经超期，就不返回给前端该记录
                if( memoryEntities.get(i).getIsRepeat() == 0  && todayDate.isAfter(memoryDate)){
                    System.out.println("超期且不重复，该记录不传回前端，memoryId="+memoryEntities.get(i).getMemoryId());
                    continue;//如果今天超过了纪念日的日期且该纪念日不重复，则该纪念日记录不返回前端
                }
                //不重复未超期或重复未超期都返回记录
                if(todayDate.isBefore(memoryDate)){
                    long dayNum= todayDate.until(memoryDate, ChronoUnit.DAYS);
                    System.out.println("不重复未超期或重复未超期都返回记录，daynum="+dayNum+",id="+memoryEntities.get(i).getMemoryId());
                    getAllMemoryVo.setDayNum(Converter.getAsInteger(dayNum));
                    getAllMemoryVo.setMemoryId(memoryEntities.get(i).getMemoryId());
                    getAllMemoryVo.setMemoryDate( memoryEntities.get(i).getMemoryDate());
                    getAllMemoryVo.setMemoryTitle( memoryEntities.get(i).getMemoryTitle());
                    getAllMemoryVo.setType( memoryEntities.get(i).getType());
                    getAllMemoryVo.setIsRepeat( memoryEntities.get(i).getIsRepeat());
                    getAllMemoryVOList.add(getAllMemoryVo);
                    continue;
                }
                //重复但超期,修改年份且返回记录
                if(memoryEntities.get(i).getIsRepeat() == 1 && todayDate.isAfter(memoryDate)){
//                    int nextYear = memoryDate.getYear()+1;
                    int nextYear = todayDate.getYear()+1;
                    Memory memoryEntity = memoryEntities.get(i);
                    LocalDate nextMemoryDate = LocalDate.of(nextYear,memoryDate.getMonthValue(),memoryDate.getDayOfMonth());
                    memoryEntity.setMemoryDate(nextMemoryDate);
                    QueryWrapper wrapper1 = new QueryWrapper();
                    wrapper1.eq("memory_id",memoryEntities.get(i).getMemoryId());
                    memoryService.update(memoryEntity,wrapper1);

                    long dayNum= todayDate.until(nextMemoryDate, ChronoUnit.DAYS);
                    System.out.println("重复但超期,修改年份且返回记录，daynum="+dayNum+"新纪念日日期为："+nextMemoryDate+",id="+memoryEntities.get(i).getMemoryId());
                    getAllMemoryVo.setDayNum(Converter.getAsInteger(dayNum));
                    getAllMemoryVo.setMemoryId(memoryEntities.get(i).getMemoryId());
                    getAllMemoryVo.setMemoryDate( memoryEntities.get(i).getMemoryDate());
                    getAllMemoryVo.setMemoryTitle( memoryEntities.get(i).getMemoryTitle());
                    getAllMemoryVo.setType( memoryEntities.get(i).getType());
                    getAllMemoryVo.setIsRepeat( memoryEntities.get(i).getIsRepeat());
                    getAllMemoryVOList.add(getAllMemoryVo);
                    continue;
                }

            }

        }
        if(memoryEntities.size() !=0){
            return ApiResponse.<List<GetAllMemoryVO>>builder().code(200).message("获取成功").data(getAllMemoryVOList).build();
        }else{
            return ApiResponse.<List<GetAllMemoryVO>>builder().code(400).message("获取失败").data(null).build();
        }

    }

    @ApiOperation(value = "纪念日页/查找某用户的所有纪念日", notes = "dayNum：间隔天数。type=1时为正计时天数，type=2时为倒计时天数。")
    @GetMapping("/getMemory/{userId}")
    @ResponseBody
    public ApiResponse<GetMemoryVO> getMyTypeMemory(@ApiParam(value="用户id",required = true) @PathVariable(value="userId",required=true) Integer userId) {

        /*查询正计时的纪念日，且要求纪念日日期必须小于等于今天*/
        QueryWrapper<Memory> wrapperCount = new QueryWrapper<>();
        wrapperCount.eq("user_id",userId).eq("type",1);
        wrapperCount.le("memory_date",LocalDate.now());
        List<Memory> countMemoryEntities = memoryService.list(wrapperCount);
        //对得到的正计时纪念日进行处理，只需计算出天数即可
        List<CountMemory> countMemoryVOList = new ArrayList<>();
        for(int i=0;i<countMemoryEntities.size();i++){
            CountMemory countMemoryVO = new CountMemory();
            LocalDate memoryDate = countMemoryEntities.get(i).getMemoryDate();
            long dayNum= memoryDate.until(LocalDate.now(), ChronoUnit.DAYS);
            countMemoryVO.setDayNum(Converter.getAsInteger(dayNum));
            countMemoryVO.setMemoryId(countMemoryEntities.get(i).getMemoryId());
            countMemoryVO.setMemoryDate(countMemoryEntities.get(i).getMemoryDate());
            countMemoryVO.setMemoryTitle(countMemoryEntities.get(i).getMemoryTitle());
            countMemoryVO.setType( countMemoryEntities.get(i).getType());
            countMemoryVOList.add(countMemoryVO);
        }

        /*查询倒计时的纪念日，要求纪念日日期需大于等于今天日期.由于我返回的记录已经对日期做了筛选，所以后续的判断会容易一些*/
        QueryWrapper<Memory> wrapperCountDown = new QueryWrapper<>();
        wrapperCountDown.eq("user_id",userId).eq("type",2);
        wrapperCountDown.ge("memory_date",LocalDate.now());
        List<Memory> countDownMemoryEntities = memoryService.list(wrapperCountDown);
        //对倒计时纪念日进行处理，还需判断是否重复进行不同处理
        List<CountDownMemory> countDownMemoryVOList = new ArrayList<>();
        for(int j=0;j < countDownMemoryEntities.size();j++){
            CountDownMemory countDownMemoryVO = new CountDownMemory();
            LocalDate memoryDate = countDownMemoryEntities.get(j).getMemoryDate();
            long dayNum= LocalDate.now().until(memoryDate, ChronoUnit.DAYS);
            //如果该倒计时纪念日没有设置年重复，那么直接计算天数并返回即可。因为如果今天还未到纪念日，就返回天数；如果今天已经是倒计时最后一天，由于不重复，所以只需返回日期但不更新纪念日日期
            //如果该纪念日设置重复，那么如果该纪念日还在未来，那么只需计算天数并直接返回。
            //只有该纪念日设置了重复，且今天就是纪念日，那么倒计时天数为0，且需要更新纪念日
            if(countDownMemoryEntities.get(j).getIsRepeat() == 1 && memoryDate.equals(LocalDate.now()) ==false) {
                countDownMemoryVO.setDayNum(Converter.getAsInteger(dayNum));
                int nextYear = LocalDate.now().getYear()+1;
                Memory memoryEntity = countDownMemoryEntities.get(j);
                LocalDate nextMemoryDate = LocalDate.of(nextYear,memoryDate.getMonthValue(),memoryDate.getDayOfMonth());
                memoryEntity.setMemoryDate(nextMemoryDate);
                QueryWrapper wrapperUpdate = new QueryWrapper();
                wrapperUpdate.eq("memory_id",countDownMemoryEntities.get(j).getMemoryId());
                memoryService.update(memoryEntity,wrapperUpdate);
            }
            countDownMemoryVO.setDayNum(Converter.getAsInteger(dayNum));
            countDownMemoryVO.setMemoryId(countDownMemoryEntities.get(j).getMemoryId());
            countDownMemoryVO.setMemoryDate(countDownMemoryEntities.get(j).getMemoryDate());
            countDownMemoryVO.setMemoryTitle(countDownMemoryEntities.get(j).getMemoryTitle());
            countDownMemoryVO.setType(countDownMemoryEntities.get(j).getType());
            countDownMemoryVOList.add(countDownMemoryVO);
        }

        //将两个列表都加到新的vo中
        GetMemoryVO getMemoryVO =new GetMemoryVO();
        getMemoryVO.setCountMemoryList(countMemoryVOList);
        getMemoryVO.setCountDownMemoryList(countDownMemoryVOList);

        if(countMemoryVOList.size() ==0 && countDownMemoryVOList.size() ==0 ){
            return ApiResponse.<GetMemoryVO>builder().code(400).message("获取失败").data(null).build();
        }else{
            return ApiResponse.<GetMemoryVO>builder().code(200).message("获取成功").data(getMemoryVO).build();
        }

    }

}

